#pragma once

#include "eventfd_sender.h"
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/steady_timer.hpp>
#include <memory>
#include <vector>
#include <mutex>
#include <chrono>

using namespace boost::asio;

/**
 * EventFD Domain Socket 发送器（客户端）
 */
class EventFdDomainSocketSender : public EventFdSender {
private:
    
    struct ConnectionInfo {
        int socket_fd;
        std::unique_ptr<posix::stream_descriptor> descriptor;
        std::string peer_info;
        std::chrono::steady_clock::time_point connect_time;
        
        ConnectionInfo();
        void reset();
    };

public:
    explicit EventFdDomainSocketSender(io_context& io,
                                     const std::string& socket_path,
                                     const std::string& identifier = "eventfd_transfer");
    ~EventFdDomainSocketSender() override;
    
    bool start() override;
    void stop() override;
    void async_send_eventfd(int eventfd, TransferCallback callback) override;
    
    /**
     * 发送带有扩展信息的EventFD
     */
    void async_send_eventfd_with_info(int eventfd, 
                                     const std::string& message_type,
                                     const std::string& topic_name,
                                     const std::string& custom_data,
                                     uint32_t message_id = 0,
                                     uint32_t priority = 0,
                                     uint32_t flags = 0,
                                     TransferCallback callback = nullptr);
    
    /**
     * 获取连接数量
     */
    size_t connection_count() const;

private:
    std::string socket_path_;
    std::vector<std::unique_ptr<ConnectionInfo>> connections_;
    std::unique_ptr<steady_timer> connect_timer_;
    std::unique_ptr<steady_timer> retry_timer_;
    mutable std::mutex connections_mutex_;
    
    bool start_client();
    void initiate_connection_with_timeout(int eventfd);
    void create_client_connection(int eventfd);
    void send_eventfd_to_connection(int eventfd, size_t connection_index);
    void send_eventfd_to_connection_with_info(int eventfd, size_t connection_index,
                                             const std::string& message_type,
                                             const std::string& topic_name,
                                             const std::string& custom_data,
                                             uint32_t message_id,
                                             uint32_t priority,
                                             uint32_t flags);
    void schedule_retry(int eventfd);
    int send_fd(int socket_fd, int fd_to_send);
    int send_fd_with_info(int socket_fd, int fd_to_send, const TransferMessage& msg);
};
